class EventTarget{
    constructor(){
        //初始化一个空对象，用于保存事件类型和它对应的回调函数数组
        this.listeners = {};
    }
    addEventListener(type,callback){//add bind attach on
        //取出此type事件对应的回调函数数组
        let callbacks = this.listeners[type];
        if(callbacks){//如果不是第一次，则向老数组中添加一个新的元素
            callbacks.push(callback);
        }else{//如果是第一次添加，则callbacks肯定是 undefined，赋值为新数组
            callbacks=[callback]
        }
        //最后再保存新数组到listeners对象中
        this.listeners[type]=callbacks;
    }
    removeEventListener(type,callback){
        //取出此type事件对应的回调函数数组
        const callbacks = this.listeners[type];
        //1.filter
        //遍历老数组，判断老数组里的元素是不是等于callback,也就是需要被移除的函数
        //如果不相等，则返回true,留在数组中，如果相等，就返回false,过滤掉了
        //最终会返回一个不包括callback对应的新数组
        //callbacks=callbacks.filter(item => item !== callback);
        //this.listeners[type]=callbacks;
        //2.splice
        //遍历callbacks数组中的每个元素
        for(let i=0;i<callbacks.length;i++){
            //如果遍历到的索引的元素等于将要被 删除的函数
            if(callbacks[i] === callback){
                //从索引为i的位置 ，删除1个元素
                callbacks.splice(i,1);
                return;
            }
        }
        //3.findIndex
        //从数组中查找callback这个函数对应的索引
        let index = callbacks.findIndex(callback);
        if(index !==-1){
            callbacks.splice(index,1);
        }
    }
    dispatchEvent(event){//dispatch、emit、trigger
        //取出此type事件对应的回调函数数组
        const callbacks = this.listeners[event.type];
        //遍历回调函数的数组，取出每一个回调函数依次执行，并传入事件对象
        callbacks.forEach(callback=>callback(event));
    }
}
const eventTarget = new EventTarget();
const handleClick = ()=>console.log('clicked');
eventTarget.addEventListener('click',handleClick);
const myEvent = new Event('click');
eventTarget.dispatchEvent(myEvent);
eventTarget.removeEventListener('click',handleClick);
eventTarget.dispatchEvent(myEvent);